package tree;

import java.io.*;
import java.util.ArrayList;

public class Scanner
{
    public int line=1;
    private char ch;
    private int asc;
    String str;
    int num=0;
    private boolean getNext=true;
    private SymTable tbl;
    ArrayList<Character> list=new ArrayList();
    public Scanner()
    {
        tbl = new SymTable(); //initialize symbol table
    }
    private void read() throws IOException {
        File file = new File("D:\\java_project\\u\\src\\file\\code.txt");
        if (file.isFile() && file.exists()) { //判断文件是否存在
            InputStreamReader read = new InputStreamReader(
                    new FileInputStream(file));//考虑到编码格式
            BufferedReader bufferedReader = new BufferedReader(read);
            int lineTxt;
            while ((lineTxt = bufferedReader.read()) != -1) {
                list.add((char)lineTxt);
//                System.out.println((char)lineTxt);
            }
            read.close();
        }
    }
    private void getNextChar() throws IOException {
        read();
        ch=list.get(num);
        num++;
        System.out.println(ch);
    }

    public Token getNextToken () throws IOException {
        if(getNext)
            getNextChar();
        else
            getNext=true;

        while(ch==' ' || ch=='\t' || ch=='\r' || ch=='\n')
        {
            if(ch=='\n')
                line++;
            getNextChar();
        }

        if(ch=='&')
        {
            getNextChar();
            if(ch=='&')     //match &&
                return (new Token(Tag.AND));
            else
            {
                System.out.println("missing &: line" + line); //error
                System.exit(-1);
            }
        }
        else if(ch=='|')
        {
            getNextChar();
            if(ch=='|')     //match ||
                return (new Token(Tag.OR));
            else
            {
                System.out.println("missing |: line " + line); //error
                System.exit(-1);
            }
        }
        else if(ch=='=')
        {
            getNextChar();  //look ahead
            if(ch=='=')     //match ==
                return (new Token(Tag.EQ));
            else
            {
                getNext=false;
                return (new Token(Tag.SET));
            }
        }
        else if(ch=='!')
        {
            getNextChar(); //look ahead
            if(ch=='=')     //match !=
                return (new Token(Tag.NE));
            else
            {
                getNext=false;
                return (new Token(Tag.NOT));
            }
        }
        else if(ch=='<')
        {
            getNextChar();  //look ahead
            if(ch=='=')     //match <=
                return (new Token(Tag.LE));
            else
            {
                getNext=false;
                return (new Token(Tag.LT));
            }
        }
        else if(ch=='>')
        {
            getNextChar(); //look ahead
            if(ch=='=')     //match >=
                return (new Token(Tag.GE));
            else
            {
                getNext=false;
                return (new Token(Tag.GT));
            }
        }
        else if(ch=='+')
            return (new Token(Tag.ADD));
        else if(ch=='-')
            return (new Token(Tag.SUB));
        else if(ch=='*')
            return (new Token(Tag.MUL));
        else if(ch=='/')
            return (new Token(Tag.DIV));
        else if(ch=='(')
            return (new Token(Tag.LP));
        else if(ch==')')
            return (new Token(Tag.RP));
        else if(ch=='{')
            return (new Token(Tag.LB));
        else if(ch=='}')
            return (new Token(Tag.RB));
        else if(ch=='[')
            return (new Token(Tag.LSB));
        else if(ch==']')
            return (new Token(Tag.RSB));
        else if(ch==';')
            return (new Token(Tag.SC));
        else if(ch=='$')
            return (new Token(Tag.END));
        else if( Character.isDigit(ch) ) {
            int v = 0;
            do {
                v = 10*v + Character.digit(ch, 10);
                getNextChar();
            } while( Character.isDigit(ch) );
            getNext=false;
            return (new Token(Tag.NUM, Integer.toString(v)));
        }
        else if( Character.isLetter(ch) ) {
            StringBuffer b = new StringBuffer(); //string buffer
            do {
                b.append(ch);
                getNextChar();
            } while( Character.isLetterOrDigit(ch) );

            getNext=false;
            String s = b.toString();
            int tag=tbl.find(s);

            if(tag<0)
            {
                tbl.reserve(s, Tag.ID); //insert to symbol table
                return (new Token(Tag.ID, s));
            }
            else if(tag==Tag.ID)
                return (new Token(Tag.ID, s));
            else
                return (new Token(tag));
        }
        else
        {
            System.out.println("Lexical error: line "+line+", "+ch);
            System.exit(-1);
        }
        return null;
    }//end-of-getToken
}